// <copyright file="DiskFileConfigurationRepository.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace Ocelot.Configuration.Repository
{
    using Microsoft.AspNetCore.Hosting;
    using Newtonsoft.Json;
    using Ocelot.Configuration.ChangeTracking;
    using Ocelot.Configuration.File;
    using Ocelot.Responses;
    using System;
    using System.Threading.Tasks;

    public class DiskFileConfigurationRepository : IFileConfigurationRepository
    {
        private readonly IOcelotConfigurationChangeTokenSource changeTokenSource;
        private readonly string environmentFilePath;
        private readonly string ocelotFilePath;
        private static readonly object Lock = new object();
        private const string ConfigurationFileName = "ocelot";

        public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource)
        {
            this.changeTokenSource = changeTokenSource;
            this.environmentFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";

            this.ocelotFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}.json";
        }

        public Task<Response<FileConfiguration>> Get()
        {
            string jsonConfiguration;

            lock (Lock)
            {
                jsonConfiguration = System.IO.File.ReadAllText(this.environmentFilePath);
            }

            var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration);

            return Task.FromResult<Response<FileConfiguration>>(new OkResponse<FileConfiguration>(fileConfiguration));
        }

        public Task<Response> Set(FileConfiguration fileConfiguration)
        {
            string jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);

            lock (Lock)
            {
                if (System.IO.File.Exists(this.environmentFilePath))
                {
                    System.IO.File.Delete(this.environmentFilePath);
                }

                System.IO.File.WriteAllText(this.environmentFilePath, jsonConfiguration);

                if (System.IO.File.Exists(this.ocelotFilePath))
                {
                    System.IO.File.Delete(this.ocelotFilePath);
                }

                System.IO.File.WriteAllText(this.ocelotFilePath, jsonConfiguration);
            }

            this.changeTokenSource.Activate();
            return Task.FromResult<Response>(new OkResponse());
        }
    }
}
